﻿using System.Linq;
using System.Web.UI;
using System.Collections.Generic;

namespace N2.Web.UI
{
	using Resources;
	
	public static class PageExtensions
	{
		public static void IncludeStyleSheet(this Page page, string relativePath)
		{
			Register.StyleSheet(page, relativePath);
		}

		public static void IncludeStyleSheet(this Control control, string relativePath)
		{
			control.Page.IncludeStyleSheet(relativePath);
		}

		public static void IncludeResourceSet(
			this Control control,
			string relativebaseResourcePath,
			ResourceType resourceType)
		{
			IncludeResourceSet(
				control,
				relativebaseResourcePath,
				resourceType,
				string.Empty);
		}

		public static void IncludeResourceSet(
			this Control control,
			string relativebaseResourcePath,
			ResourceType resourceType,
			string setName)
		{
			var _setName = string.IsNullOrEmpty(setName)
				? resourceType == ResourceType.Css
					? "Css"
					: resourceType == ResourceType.JavaScript
						? "Js"
						: "Resource"
				: setName ;
			//TODO combine path parts with VirtuaPathUtility
			var _path = relativebaseResourcePath + "/" + _setName + ".axd";

			if(resourceType == ResourceType.Css) {
				Register.StyleSheet(control.Page, _path);
			} else if(resourceType == ResourceType.JavaScript) {
				Register.JavaScript(control.Page, _path);
			}
		}

		public static Control Find(this Control owner, string selector)
		{
			var _namingContainers = selector.Split(' ', ',', '>', '/');
			Control _result = owner;
			int i;
			
			for (i = 0; i < _namingContainers.Length && null != _result; i++) {
				_result = _result.FindControl(_namingContainers[i].Trim());
			}
			
			return i == _namingContainers.Length ? _result : null;
		}
		
		/// <summary>
		/// Traverses a child control hierarchy
		/// to find all first occurences of a given type
		/// </summary>
		/// <typeparam name="T">Control type to find, may also be an interface</typeparam>
		/// <param name="owner">Parent control</param>
		/// <returns></returns>
		/// http://www.codinghorror.com/blog/archives/000307.html
		public static IEnumerable<T> FindRecursive<T>(this Control owner)
			where T:class
		{
			return
				owner is T
					? new[] { owner as T }
					: owner.Controls
						.OfType<Control>()
						.Aggregate(
							Enumerable.Empty<T>(),
							(_list, _next) => _list.Concat(_next.FindRecursive<T>()));
		}
	}
}
